package com.scs.application.core.mvc.controller;

import cn.hutool.core.util.ClassUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.scs.application.core.export.ExportParamDto;
import com.scs.application.core.model.CommonResult;
import com.scs.application.core.model.PageResult;
import com.scs.application.core.model.RestResult;
import com.scs.application.core.service.IBaseService;
import com.scs.application.core.utils.DateUtils;
import com.scs.application.core.utils.StringUtils;
import com.scs.application.core.utils.UserUtils;
import com.scs.application.core.utils.UtilNum;
import com.scs.application.modules.base.entity.HospitalSupplier;
import com.scs.application.modules.base.entity.Supplier;
import com.scs.application.modules.base.entity.SysLog;
import com.scs.application.modules.base.request.HospitalSupplierQueryRequest;
import com.scs.application.modules.base.service.HospitalSupplierService;
import com.scs.application.modules.base.service.SysLogService;
import com.scs.application.modules.design.service.QueryGenerator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description: 通用增删改查
 */
public abstract class CrudController<E extends Serializable, ID extends Serializable, S extends IBaseService<E>>
        extends BaseController {

    @Autowired
    protected S service;

    @Autowired
    protected HospitalSupplierService hospitalSupplierService;

    @Autowired
    protected SysLogService sysLogService;

    protected final Logger logger = LoggerFactory.getLogger(this.getClass());


    // 添加操作日志-成功
    public void syslogSuccess(String moduleType,String busType,String busId,String busKey,String busUser,String remark) {
        SysLog sysLog = new SysLog();
        sysLog.setLogType(SysLog.LogType.success).setOpTime(DateUtils.now());
        sysLog.setModuleType(moduleType).setBusType(busType).setBusId(busId).setBusKey(busKey).setBusUser(busUser).setRemark(remark);
        sysLogService.save(sysLog);
    }


    @PostMapping
    public CommonResult add(@RequestBody @Valid E entity) {
        boolean bSave = service.saveCascadeById(entity);
        return bSave ? CommonResult.ok("新增成功", entity) : CommonResult.error("新增失败", entity);
    }

    @PutMapping
    public CommonResult update(@RequestBody @Valid E entity) {
        boolean bUpdate = service.updateCascadeById(entity);
        return bUpdate ? CommonResult.ok("保存成功", entity) : CommonResult.error("保存失败", entity);
    }


    @DeleteMapping("/{id}")
    public CommonResult deleteById(@PathVariable("id") ID id) {
        boolean bRemove = service.removeCascadeById(id);
        return bRemove ? CommonResult.ok("删除成功") : CommonResult.error("删除失败");

    }

    @DeleteMapping("/batch_delete")
    public CommonResult deleteByIds(@RequestBody String[] ids) {
        boolean bRemove = service.removeCascadeBatchByIds(Lists.newArrayList(ids));
        return bRemove ? CommonResult.ok("删除成功") : CommonResult.error("删除失败");
    }

    @GetMapping("/{id}")
    public CommonResult<E> get(@PathVariable("id") ID id) {
        E result = service.getById(id);
        return CommonResult.ok(result != null ? "查询成功" : "查询失败", result);
    }

    /***
     * @date: 2024/6/24
     * @Description:  添加数据过滤条件
     */
    protected void fillQueryAuth(QueryWrapper queryWrapper,E entity) {
        if (UserUtils.isAdmin()) {
            return;
        }
        // 表中有医院字段
        if (ClassUtil.getDeclaredField(entity.getClass(), "hospitalId") != null)  {
            // 只筛选有供货关系的医院
            if (UserUtils.isSupplier()) {
                HospitalSupplierQueryRequest hospitalSupplierQueryRequest = new HospitalSupplierQueryRequest();
                hospitalSupplierQueryRequest.setSupplierId(UserUtils.getSupplierId());
                List<HospitalSupplier> hospitalSupplierList = hospitalSupplierService.list(hospitalSupplierQueryRequest);
                if (!hospitalSupplierList.isEmpty()) {
                    List<String> hospitalIdList = hospitalSupplierList.stream().map(HospitalSupplier::getHospitalId).distinct().collect(Collectors.toList());
                    queryWrapper.in("ifnull(hospital_id, '')", hospitalIdList);
                } else{
                    queryWrapper.eq("1","0");
                }
            }
            // 只筛选当前医院
            if (UserUtils.isHospital()) {
                queryWrapper.eq("ifnull(hospital_id, '')", UserUtils.getHospitalId());
            }
        }

        // 表中有供应商字段
        if (ClassUtil.getDeclaredField(entity.getClass(), "supplierId") != null) {
            // 只筛选当前供应商的数据
            if (UserUtils.isSupplier()) {
                queryWrapper.eq("ifnull(supplier_id, '')", UserUtils.getSupplierId());
            }
            // 只筛选当前医院有供货关系的供应商数据
            if (UserUtils.isHospital()) {
                HospitalSupplierQueryRequest hospitalSupplierQueryRequest = new HospitalSupplierQueryRequest();
                hospitalSupplierQueryRequest.setHospitalId(UserUtils.getHospitalId());
                List<HospitalSupplier> hospitalSupplierList = hospitalSupplierService.list(hospitalSupplierQueryRequest);
                if (!hospitalSupplierList.isEmpty()) {
                    List<String> supIdList = hospitalSupplierList.stream().map(HospitalSupplier::getSupplierId).distinct().collect(Collectors.toList());
                    queryWrapper.in("ifnull(supplier_id, '')", supIdList);
                } else{
                    queryWrapper.eq("1","0");
                }
            }
        }

        // 供应商表
        if (entity instanceof Supplier) {
            // 只筛选当前供应商的数据
            if (UserUtils.isSupplier()) {
                queryWrapper.eq("id", UserUtils.getSupplierId());
            }
            // 只筛选当前医院有供货关系的供应商数据
            if (UserUtils.isHospital()) {
                HospitalSupplierQueryRequest hospitalSupplierQueryRequest = new HospitalSupplierQueryRequest();
                hospitalSupplierQueryRequest.setHospitalId(UserUtils.getHospitalId());
                List<HospitalSupplier> hospitalSupplierList = hospitalSupplierService.list(hospitalSupplierQueryRequest);
                if (!hospitalSupplierList.isEmpty()) {
                    List<String> supIdList = hospitalSupplierList.stream().map(HospitalSupplier::getSupplierId).distinct().collect(Collectors.toList());
                    queryWrapper.in("id", supIdList);
                } else{
                    queryWrapper.eq("1","0");
                }
            }
        }
    }

    /***
     * @param request
     * @Description:  通用分页
     */
    @GetMapping("/pageCommon")
    public PageResult pageCommon(HttpServletRequest request,E entity) {
        IPage<E> page = QueryGenerator.parsePage(request);
        QueryWrapper<E> queryWrapper = QueryGenerator.initQueryWrapper(request);
        fillQueryAuth(queryWrapper,entity);
        IPage pageResult = service.page(page, queryWrapper);
        return PageResult.ok("查询成功", pageResult.getRecords(), pageResult.getTotal());
    }

    /***
     * @param request
     * @Description:  通用分页
     */
    @GetMapping("/listCommon")
    public CommonResult listCommon(HttpServletRequest request,E entity) {
        QueryWrapper<E> queryWrapper = QueryGenerator.initQueryWrapper(request);
        fillQueryAuth(queryWrapper,entity);
        return CommonResult.ok("查询成功", service.list(queryWrapper));
    }

    /***
     * @param entity
     * @Description:  通用保存、更新
     */
    @PostMapping("/saveOrUpdateCommon")
    public RestResult saveOrUpdateCommon(@Valid @RequestBody E entity) {
        boolean isOk = service.saveOrUpdate(entity);
        if (!isOk) {
            return RestResult.error("数据保存失败");
        }
        return RestResult.ok("数据保存成功", entity);
    }

    /***
     * @param id
     * @Description:  通用查找，单个
     */
    @GetMapping("/findByIdCommon")
    public RestResult findByIdCommon(@RequestParam("id") Serializable id) {
        E entity = service.getById(id);
        if (entity == null) {
            return RestResult.error("数据查询失败<br>可能所操作数据已被删除，请刷新后重新尝试操作");
        }
        return RestResult.ok("获取数据成功", entity);
    }

    /***
     * @Description:  通用删除，多个
     */
    @DeleteMapping("/deleteBatchCommon")
    public RestResult deleteBatchCommon(@RequestBody Map<String, Object> para) {
        List<Serializable> ids = (List<Serializable>) para.get("ids");
        Boolean isOk = service.removeCascadeBatchByIds(ids);
        if (!isOk) {
            return RestResult.error("数据删除失败<br>可能所操作数据已被删除，请刷新页面重新尝试操作");
        }
        return RestResult.ok("数据删除成功");
    }

    public Map<String, Double> getMapNum(String sumFields,List list){
        String[] sumFieldArr = sumFields.split(",");
        //暂时使用以下遍历方法
        Map<String, Double> mapNum = new HashMap<String, Double>();
        for (Object od : list) {
            JSONObject jsonOb = JSON.parseObject(JSON.toJSONString(od));
            for (String field : sumFieldArr) {
                if (!mapNum.containsKey(field)) mapNum.put(field, 0d);
                jsonOb.keySet().stream().filter(key -> key.toLowerCase().equalsIgnoreCase(field)).findFirst().ifPresent( keyFind -> {
                    mapNum.put(field, UtilNum.sum(mapNum.get(field), jsonOb.getString(keyFind)));
                });
            }
        }
        return mapNum;
    }

    //顶部合计
    @GetMapping("/sumTop")
    protected RestResult sumTop(String sumFields, HttpServletRequest request, E entity) {
        if (StringUtils.isBlank(sumFields)) {
            return RestResult.ok("查询成功", null);
        }
        QueryWrapper<E> queryWrapper = QueryGenerator.initQueryWrapper(request);
        fillQueryAuth(queryWrapper,entity);
        List list = service.list(queryWrapper);
        if (list == null || list.size() < 1) {
            return RestResult.ok("查询成功", null);
        }
        return RestResult.ok("查询成功", getMapNum(sumFields,list));
    }


    @GetMapping("/exportFullData")
    public RestResult exportFullData(@RequestParam Map<String, String> reqData,HttpServletRequest request,E entity) throws Exception {
        QueryWrapper<E> queryWrapper = QueryGenerator.initQueryWrapper(request);
        fillQueryAuth(queryWrapper,entity);
        ExportParamDto exportParams = JSON.parseObject(JSON.toJSONString(reqData), ExportParamDto.class);
        Map<String, Object> userParam = null;
        //固定参数
        if (reqData.containsKey("userParam")) {
            JSONObject ob = JSON.parseObject(reqData.get("userParam") + "");
            userParam = Maps.newHashMap(ob);
        }
        return RestResult.ok("查询成功", service.exportFullData(queryWrapper, exportParams, userParam,request));
    }
}
